home *** CD-ROM | disk | FTP | other *** search
/ Software 2000 / Software 2000 Volume 1 (Disc 1 of 2).iso / utilities / u118.dms / in.adf / top / func.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-12-06  |  5.2 KB  |  252 lines

  1. /* Copyright (c) 1988 by Sozobon, Limited.  Author: Tony Andrews
  2.  *
  3.  * Permission is granted to anyone to use this software for any purpose
  4.  * on any computer system, and to redistribute it freely, with the
  5.  * following restrictions:
  6.  * 1) No charge may be made other than reasonable charges for reproduction.
  7.  * 2) Modified versions must be clearly marked as such.
  8.  * 3) The authors are not responsible for any harmful consequences
  9.  *    of using this software, even if they result from defects in it.
  10.  */
  11. #include "top.h"
  12.  
  13. BLOCK    *fhead;        /* head of the current function */
  14.  
  15. /*
  16.  * dofunc() - process one function
  17.  *
  18.  * Returns FALSE on end of file
  19.  */
  20. bool
  21. dofunc()
  22. {
  23.     BLOCK    *getfunc();
  24.  
  25. #ifdef    DEBUG
  26.     if (debug)
  27.         fprintf(stderr, "dofunc() - calling getfunc()\n");
  28. #endif
  29.     if ((fhead = getfunc()) == NULL)
  30.         return FALSE;
  31.  
  32.  
  33.     /*
  34.      * Process the function we just read
  35.      */
  36.     bopt(fhead);    /* perform branch optimization (must be done first) */
  37.  
  38.     if (do_dflow)
  39.         rhealth(fhead);    /* perform live/dead register analysis */
  40.  
  41.     if (do_peep)
  42.         peep(fhead);    /* peephole optimizations */
  43.  
  44.     /*
  45.      * Now dump out the modified tree
  46.      */
  47. #ifdef    DEBUG
  48.     if (debug)
  49.         fprintf(stderr, "dofunc() - calling putfunc()\n");
  50. #endif
  51.     putfunc(fhead);
  52.  
  53. #ifdef    DEBUG
  54.     if (debug)
  55.         fprintf(stderr, "dofunc() - calling freesym()\n");
  56. #endif
  57.     freesym();        /* free the symbol table */
  58.  
  59.     return TRUE;
  60. }
  61.  
  62. static    bool    saw_eof = FALSE;
  63.  
  64. /*
  65.  * getfunc() - get a function and return a pointer to its starting block
  66.  *
  67.  * Returns NULL on end of file.
  68.  */
  69. BLOCK *
  70. getfunc()
  71. {
  72.     register BLOCK    *head;    /* starting block for this function */
  73.     register BLOCK    *ob;    /* the last block we read */
  74.     register BLOCK    *cb;    /* the block we're currently reading */
  75.  
  76.     if (saw_eof)
  77.         return NULL;
  78.  
  79.     head = NULL;
  80.  
  81.     /*
  82.      * Starting a global function
  83.      */
  84. #ifdef NORTHC
  85.     if (stricmp(t_op, "XDEF") == 0) {
  86. #else
  87.     if (strcmp(t_op, ".globl") == 0) {
  88. #endif
  89.         /*
  90.          * Enter the symbol and mark it global.
  91.          */
  92.         head = mksym(t_arg);
  93.         head->flags |= B_GLOBAL;
  94.     
  95.         readline();
  96.     }
  97.  
  98.     ob = NULL;
  99.  
  100.     for (;;) {
  101.         if (ob == NULL) {
  102.             if (t_lab[0] != '_') {
  103.                 fprintf(stderr, "top: expected function label\n");
  104.                 exit(EXIT_FAILURE);
  105.             }
  106.             if (head == NULL)
  107.                 head = mksym(t_lab);
  108.  
  109.         } else if (t_lab[0] == '\0') {
  110.             fprintf(stderr, "top: expected block label\n");
  111.             exit(EXIT_FAILURE);
  112.         }
  113.  
  114.         if ((cb = getsym(t_lab)) == NULL)
  115.             cb = mksym(t_lab);
  116.  
  117.         /*
  118.          * The last block falls through to this one.
  119.          */
  120.         if (ob != NULL) {
  121.             ob->chain = cb;
  122.             ob->next = cb;
  123.             ob->bfall = cb;
  124.         }
  125.  
  126.         t_lab[0] = '\0';
  127.  
  128.         /*
  129.          * Now read lines until we hit a new block or another
  130.          * function.
  131.          */
  132.         for (;;) {
  133.             /*
  134.              * If we see a global, we're done with the function
  135.              */
  136. #ifdef NORTHC
  137.             if (stricmp(t_op, "xdef") == 0)
  138. #else
  139.             if (stricmp(t_op, ".globl") == 0)
  140. #endif
  141.                 return head;
  142.             /*
  143.              * If we see a function label, we're done too.
  144.              */
  145.             if (t_lab[0] == '_')
  146.                 return head;
  147.             /*
  148.              * If we see any other label, we're done with the block.
  149.              */
  150.             if (t_lab[0])
  151.                 break;
  152.  
  153.             addinst(cb, t_op, t_arg);
  154.  
  155.             /*
  156.              * If we're at EOF, note the we've hit the end of
  157.              * file, but return the function we just read.
  158.              */
  159.             if (!readline()) {
  160.                 saw_eof = TRUE;
  161.                 return head;
  162.             }
  163.         }
  164.         ob = cb;
  165.     }
  166. }
  167.  
  168. /*
  169.  * putfunc(sb) - print out the function starting at block 'sb'
  170.  *
  171.  * The 'next' pointers determine the order in which things are placed
  172.  * in the file. Branch instructions have been removed so they need to
  173.  * be replaced here on output. Conditional branches are generated if
  174.  * indicated (by non-null 'bcond'). Unconditional branches are generated
  175.  * at the end of a block if it's "fall through" block isn't going to
  176.  * be the next thing in the file.
  177.  */
  178.  
  179. #ifdef NORTHC
  180. int sNum = 0;
  181. int out_code = 0;
  182. #endif
  183.  
  184. putfunc(sb)
  185. register BLOCK    *sb;
  186. {
  187.     register BLOCK    *cb;
  188.     register INST    *ci;
  189.  
  190. #ifdef NORTHC
  191.         if(out_code==0)
  192.            fprintf(ofp, "\tSECTION\tFNUM%d,CODE\n",sNum++);
  193.         out_code = 1;
  194.     fprintf(ofp, ";\n");
  195.     fprintf(ofp, "; %s\n", sb->name);
  196.     fprintf(ofp, ";\n");
  197. #else
  198.     fprintf(ofp, "*\n");
  199.     fprintf(ofp, "* %s\n", sb->name);
  200.     fprintf(ofp, "*\n");
  201.     fprintf(ofp, "\t.text\n");
  202. #endif
  203.  
  204.     for (cb = sb; cb != NULL ;cb = cb->next) {
  205.         if (cb->flags & B_GLOBAL)
  206. #ifdef NORTHC
  207.             fprintf(ofp, "\tXDEF\t%s\n", cb->name);
  208. #else
  209.             fprintf(ofp, "\t.globl\t%s\n", cb->name);
  210. #endif
  211.  
  212.         if (*cb->name == '_')
  213.             fprintf(ofp, "%s:\n", cb->name);
  214.  
  215.         else if (cb->flags & B_LABEL)
  216.             fprintf(ofp, "%s:\n", cb->name);
  217. #ifdef    DEBUG
  218.         if (debug) {
  219. #ifdef NORTHC
  220.             fprintf(ofp, ";\n");
  221.             fprintf(ofp, "; %s, ref:%04x  set:%04x\n",
  222.                 cb->name, cb->rref, cb->rset);
  223.             fprintf(ofp, ";\n");
  224. #else
  225.             fprintf(ofp, "*\n");
  226.             fprintf(ofp, "* %s, ref:%04x  set:%04x\n",
  227.                 cb->name, cb->rref, cb->rset);
  228.             fprintf(ofp, "*\n");
  229. #endif
  230.         }
  231. #endif
  232.  
  233.         for (ci = cb->first; ci != NULL ;ci = ci->next)
  234.             putinst(ci);
  235.         /*
  236.          * If there's a conditional branch, put out the
  237.          * appropriate instruction for it.
  238.          */
  239.         if (cb->bcond != NULL && cb->bcode >= 0)
  240.             fprintf(ofp, "\t%s\t%s\n",
  241.                 opnames[cb->bcode], cb->bcond->name);
  242.         /*
  243.          * If there's a "fall through" label, and the destination
  244.          * block doesn't come next, put out a branch.
  245.          */
  246.         if (cb->bfall != NULL && cb->bfall != cb->next) {
  247.             s_badd++;
  248.             fprintf(ofp, "\tbra\t%s\n", cb->bfall->name);
  249.         }
  250.     }
  251. }
  252.